package com.coolgor.xcode;

import java.io.*;
import java.util.List;

public class StackServiceImpl {

    public static void run(List<String[]> context,
                           String basePath,
                           String basePackage,
                           String moduleName) throws IOException {
    String outputPath = basePath + XcoderConfig.OutputPath + "/service/impl";;
        String tableName = null;
        String className = null;
        String keyColumn = null;
        String keyParam = null;
        Boolean hasCreateTime = false;
        Boolean hasLastEditTime = false;
        for (int i = 0; i < context.size(); i++) {
            switch (context.get(i)[0].toLowerCase()) {
                case "table":
                    tableName = context.get(i)[1];
                    className = StringUtil.firstUpper(context.get(i)[2]);
                    break;
                case "key":
                    keyColumn = context.get(i)[1];
                    keyParam = context.get(i)[2];
                    break;
            }
            if ("createtime".equals(context.get(i)[2].toLowerCase())) {
                hasCreateTime = true ;
            }
            if ("lastedittime".equals(context.get(i)[2].toLowerCase())) {
                hasLastEditTime = true ;
            }
        }

        // File writing ###############
        File file = new File(outputPath);
        if (!file.exists()) file.mkdirs();
        file = new File(outputPath + "/" + className + "ServiceImpl.java");
        if (!file.exists()) file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
        bw.newLine();
        if (null!=basePackage) {
            if (basePackage.length()>1 && !basePackage.endsWith(".")) {
                basePackage = basePackage + ".";
            } else {
                basePackage = "";
            }
            if (null!=moduleName && !"".equals(moduleName) && !".".equals(moduleName)) {
                bw.write("package "+basePackage+"service."+moduleName+".impl;\n");
                moduleName = moduleName+".";
            } else {
                bw.write("package "+basePackage+"service.impl;\n");
                moduleName = "";
            }
            bw.newLine();
            bw.write("import "+basePackage+"common.PageCalculator;\n");
            bw.write("import "+basePackage+"entity."+moduleName+className+";\n");
            bw.write("import "+basePackage+"dao."+moduleName+className+"Dao;\n");
            bw.write("import "+basePackage+"dto."+moduleName+className+"Execution;\n");
            bw.write("import "+basePackage+"enums."+moduleName+className+"OperationStateEnum;\n");
            bw.write("import "+basePackage+"exceptions."+moduleName+className+"OperationException;\n");
            bw.write("import "+basePackage+"service."+moduleName+className+"Service;\n");
        }
        bw.newLine();
        bw.write("import org.slf4j.Logger;\n");
        bw.write("import org.slf4j.LoggerFactory;\n");
        bw.write("import org.springframework.stereotype.Service;\n");
        bw.write("import org.springframework.transaction.annotation.Transactional;\n");
        bw.write("import org.springframework.beans.factory.annotation.Autowired;\n");
        bw.newLine();
        bw.write("import java.util.Date;\n");
        bw.write("import java.util.List;\n");
        bw.write("import java.util.ArrayList;\n");
        bw.newLine();
        bw.newLine();
        bw.write("@Service\n");
        bw.write("public class "+className+"ServiceImpl implements "+className+"Service {\n");
        bw.newLine();
        bw.write("\tprivate static Logger log = LoggerFactory.getLogger("+className+"ServiceImpl.class);\n");
        bw.newLine();
        bw.write("\t@Autowired\n");
        bw.write("\t"+className+"Dao "+StringUtil.firstLower(className)+"Dao;\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\tpublic "+className+"Execution getByID(Long "+keyParam+") {\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif (null == "+keyParam+" || "+keyParam+".equals(\"\")) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL_ID);\n");
        bw.write("\t\t}\n");
        bw.write("\t\t"+className+" "+StringUtil.firstLower(className)+" = "+StringUtil.firstLower(className)+"Dao.queryByID("+keyParam+");\n");
        bw.write("\t\tif ("+StringUtil.firstLower(className)+" != null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.SUCCESS, "+StringUtil.firstLower(className)+");\n");
        bw.write("\t\t} else {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t}\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\tpublic "+className+"Execution getList("+className+" "+StringUtil.firstLower(className)+"Condition, int pageIndex, int pageSize) {\n");
        bw.write("\t\t// 将页码转换成行码\n");
        bw.write("\t\tint rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);\n");
        bw.write("\t\t// 依据查询条件，调用dao层返回相关的查询结果列表\n");
        bw.write("\t\tList<"+className+"> list = "+StringUtil.firstLower(className)+"Dao.queryList("+StringUtil.firstLower(className)+"Condition, rowIndex, pageSize);\n");
        bw.write("\t\t// 依据相同的查询条件，返回查询结果总数\n");
        bw.write("\t\tint count = "+StringUtil.firstLower(className)+"Dao.queryCount("+StringUtil.firstLower(className)+"Condition);\n");
        bw.write("\t\t"+className+"Execution result = new "+className+"Execution();\n");
        bw.write("\t\tif (list != null) {\n");
        bw.write("\t\t\tresult.setState("+className+"OperationStateEnum.SUCCESS.getState());\n");
        bw.write("\t\t\tresult.setStateInfo("+className+"OperationStateEnum.SUCCESS.getStateInfo());\n");
        bw.write("\t\t\tresult.set"+className+"List(list);\n");
        bw.write("\t\t\tresult.setCount(count);\n");
        bw.write("\t\t} else {\n");
        bw.write("\t\t\tresult.setState("+className+"OperationStateEnum.INNER_ERROR.getState());\n");
        bw.write("\t\t}\n");
        bw.write("\t\treturn result;\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution add("+className+" "+StringUtil.firstLower(className)+") throws "+className+"OperationException {\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif ("+StringUtil.firstLower(className)+" == null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        if (hasCreateTime) {
            bw.write("\t\t\t"+StringUtil.firstLower(className)+".setCreateTime(new Date());\n");
        }
        if (hasLastEditTime) {
            bw.write("\t\t\t"+StringUtil.firstLower(className)+".setLastEditTime(new Date());\n");
        }
        bw.write("\t\t\t// 执行插入数据操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.insert("+StringUtil.firstLower(className)+");\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"信息插入失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Add "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\treturn new "+className+"Execution("+className+"OperationStateEnum.SUCCESS, "+StringUtil.firstLower(className)+");\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution modify("+className+" "+StringUtil.firstLower(className)+") throws "+className+"OperationException {\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif ("+StringUtil.firstLower(className)+" == null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        if (hasLastEditTime) {
            bw.write("\t\t\t// 把记录的最后更新时间设置为当前时间 \n");
            bw.write("\t\t\t"+StringUtil.firstLower(className)+".setLastEditTime(new Date());\n");
        }
        bw.write("\t\t\t// 执行修改更新操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.update("+StringUtil.firstLower(className)+");\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"信息更新失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Update "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\treturn new "+className+"Execution("+className+"OperationStateEnum.SUCCESS, "+StringUtil.firstLower(className)+");\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution remove(Long "+keyParam+") throws "+className+"OperationException{\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif ("+keyParam+" == null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        bw.write("\t\t\t// 执行删除操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.delete("+keyParam+");\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"单条信息删除失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Delete "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\treturn new "+className+"Execution("+className+"OperationStateEnum.SUCCESS);\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution remove("+className+" "+StringUtil.firstLower(className)+") throws "+className+"OperationException{\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif ("+StringUtil.firstLower(className)+" == null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        bw.write("\t\t\t// 执行删除操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.delete("+StringUtil.firstLower(className)+".get"+StringUtil.firstUpper(keyParam)+"());\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"单条信息删除失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Delete "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\treturn new "+className+"Execution("+className+"OperationStateEnum.SUCCESS, "+StringUtil.firstLower(className)+");\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution removeBatchByID(List<Long> recordIDList) throws "+className+"OperationException{\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif (recordIDList == null || recordIDList.size() < 1) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        bw.write("\t\t\t// 执行删除操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.deleteBatch(recordIDList);\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"多条信息批量删除失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Batch Delete "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\t"+className+"Execution exe = new "+className+"Execution("+className+"OperationStateEnum.SUCCESS);\n");
        bw.write("\t\texe.setCount(effectedNum);\n");
        bw.write("\t\treturn exe;\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("\t@Override\n");
        bw.write("\t@Transactional\n");
        bw.write("\tpublic "+className+"Execution removeBatch(List<"+className+"> "+StringUtil.firstLower(className)+"List) throws "+className+"OperationException{\n");
        bw.write("\t\t// 空值判断\n");
        bw.write("\t\tif ("+StringUtil.firstLower(className)+"List == null) {\n");
        bw.write("\t\t\treturn new "+className+"Execution("+className+"OperationStateEnum.NULL);\n");
        bw.write("\t\t} \n");
        bw.write("\t\tList<Long> recordIDList = new ArrayList<Long>();\n");
        bw.write("\t\tfor (int i=0; i<"+StringUtil.firstLower(className)+"List.size(); i++) {\n");
        bw.write("\t\t\trecordIDList.add("+StringUtil.firstLower(className)+"List.get(i).get"+StringUtil.firstUpper(keyParam)+"());\t\t\t\n");
        bw.write("\t\t}\n");
        bw.write("\t\tint effectedNum;\n");
        bw.write("\t\ttry {\n");
        bw.write("\t\t\t// 执行删除操作 \n");
        bw.write("\t\t\teffectedNum = "+StringUtil.firstLower(className)+"Dao.deleteBatch(recordIDList);\n");
        bw.write("\t\t\tif (effectedNum <= 0) {\n");
        bw.write("\t\t\t\tthrow new "+className+"OperationException(\""+className+"多条信息批量删除失败\");\n");
        bw.write("\t\t\t}\n");
        bw.write("\t\t} catch (Exception e) {\n");
        bw.write("\t\t\tthrow new "+className+"OperationException(\"Batch Delete "+StringUtil.firstLower(className)+" error:\" + e.getMessage());\n");
        bw.write("\t\t}\n");
        bw.write("\t\t"+className+"Execution exe = new "+className+"Execution("+className+"OperationStateEnum.SUCCESS);\n");
        bw.write("\t\texe.setCount(effectedNum);\n");
        bw.write("\t\treturn exe;\n");
        bw.write("\t}\n");
        bw.newLine();
        bw.write("}\n");
        bw.close();
    }
}
